package cn.edu.scau.sec.rw.controllers;

import java.awt.event.ActionListener;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ResourceBundle;

import javax.swing.Timer;

import cn.edu.scau.sec.rw.model.device_manage.Device.DeviceForProcess;
import cn.edu.scau.sec.rw.model.device_manage.Device.Device_Pcb;
import cn.edu.scau.sec.rw.model.device_manage.Device.Equipment;

import javafx.event.ActionEvent;

//import com.sun.javafx.geom.Rectangle;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
//import javafx.scene.text.Text;

public class DeviceController implements Initializable{
	private Equipment[] A,B,C;
	//待分配设备的进程列表
	List<Device_Pcb> arrr=new ArrayList<Device_Pcb>();
	//各等待列表
	List<Device_Pcb> waitA=new ArrayList<Device_Pcb>();
	List<Device_Pcb> waitB=new ArrayList<Device_Pcb>();
	List<Device_Pcb> waitC=new ArrayList<Device_Pcb>();

	@FXML
	Rectangle A1,A2,B1,B2,B3,C1,C2,C3;
	@FXML
	TextArea taA,taB,taC,taA2,taB2,taC2;
	@FXML
	Text lbe,end;
	@FXML
	Button btn,back;


	int cnt,cnt2;
	public Timer tmr;

	//时间
	public int curT=0;

	@Override
	public void initialize(URL location, ResourceBundle resources) {
		A=new Equipment[2];
		B=new Equipment[3];
		C=new Equipment[3];
		cnt=0;
		for(int i=0;i<2;i++) {
			A[i]=new Equipment("A"+(i+1));
		}
		for(int i=0;i<3;i++) {
			B[i]=new Equipment("B"+(i+1));
		}
		for(int i=0;i<3;i++) {
			C[i]=new Equipment("C"+(i+1));
		}
		end.setVisible(false);
		taA.setEditable(false);
		taB.setEditable(false);
		taC.setEditable(false);
		taA2.setEditable(false);
		taB2.setEditable(false);
		taC2.setEditable(false);
		showDetail();
	}
	public void init() {
		//时间重置
		curT=0;
		end.setVisible(false);
		for(int i=0;i<2;i++) {
			A[i].setisOccupy(false);;
		}
		for(int i=0;i<3;i++) {
			B[i].setisOccupy(false);;
		}
		for(int i=0;i<3;i++) {
			C[i].setisOccupy(false);;
		}

		waitA.clear();
		waitB.clear();
		waitC.clear();


		//这里是一个静态列表 将使用其中的进程来进行设备使用模拟
		List<Device_Pcb>Arrr= DeviceForProcess.arrr;
//Arrr
//		Arrr.clear();
//		Device_Pcb L=new Device_Pcb(1,5,"A","U");//6
//		Arrr.add(L);
//		L=new Device_Pcb(4,9,"A","F1");//13
//		Arrr.add(L);
//		L=new Device_Pcb(2,9,"C","Y");//11
//		Arrr.add(L);
//		L=new Device_Pcb(3,6,"B","H");//9
//		Arrr.add(L);
//		L=new Device_Pcb(3,2,"A","G");//5
//		Arrr.add(L);
//		L=new Device_Pcb(4,1,"B","F");//5
//		Arrr.add(L);
		//按先来后到排序
		Collections.sort(Arrr);
		arrr.clear();
		//赋值给arrr
		for(int i=0;i<Arrr.size();i++) {
			arrr.add(new Device_Pcb(Arrr.get(i)));
		}

		taA.clear();
		taB.clear();
		taC.clear();
		taA2.clear();
		taB2.clear();
		taC2.clear();
	}

	//"开始"按钮的动作事件
	//第一次按是开始cnt==0
	//第二次按是重开始cnt>=1
	//
	@FXML
	public void ready(ActionEvent event) {
		if(cnt!=0)//计次数
			tmr.stop();
//		if(arrr.isEmpty()==false)
//			cnt2+=1;
		cnt+=1;
		init();
		showDetail();
		start_();
	}
	int state_;
	@FXML
	public void backAction(ActionEvent event) {
		if(state_==1) {
			tmr.stop();
			state_=0;
		}
		else {
			tmr.restart();
			state_=1;
		}

	}
	public void clear(int curT) {//一一检查占用设备的进程是否结束 是的话释放设备资源
		for(int i=0;i<2;i++) {
			if(A[i].getisOccupy()==true) {
				if(A[i].getPossessor().end<=curT) {
					taA.appendText(""+curT+" "+A[i].getPossessor().name+" Over\n");
					A[i].clear();
				}
			}
		}
		for(int i=0;i<3;i++) {
			if(B[i].getisOccupy()==true) {
				if(B[i].getPossessor().end<=curT) {
					taB.appendText(""+curT+" "+B[i].getPossessor().name+" Over\n");
					B[i].clear();
				}
			}
		}
		for(int i=0;i<3;i++) {
			if(C[i].getisOccupy()==true) {
				if(C[i].getPossessor().end<=curT) {
					taC.appendText(""+curT+" "+C[i].getPossessor().name+" Over\n");
					C[i].clear();
				}
			}
		}
	}

	public void showDetail() {//被占有的设备资源要变色
		if(A[0].getisOccupy())
			A1.setFill(Color.YELLOW);
		else A1.setFill(Color.BLUE);

		if(A[1].getisOccupy())
			A2.setFill(Color.YELLOW);
		else A2.setFill(Color.BLUE);

		if(B[0].getisOccupy())
			B1.setFill(Color.YELLOW);
		else B1.setFill(Color.BLUE);

		if(B[1].getisOccupy())
			B2.setFill(Color.YELLOW);
		else B2.setFill(Color.BLUE);

		if(B[2].getisOccupy())
			B3.setFill(Color.YELLOW);
		else B3.setFill(Color.BLUE);

		if(C[0].getisOccupy())
			C1.setFill(Color.YELLOW);
		else C1.setFill(Color.BLUE);

		if(C[1].getisOccupy())
			C2.setFill(Color.YELLOW);
		else C2.setFill(Color.BLUE);

		if(C[2].getisOccupy())
			C3.setFill(Color.YELLOW);
		else C3.setFill(Color.BLUE);

		taA2.clear();
		taB2.clear();
		taC2.clear();
		for(int i=0;i<waitA.size();i++) {
			Device_Pcb lst=waitA.get(i);
			taA2.appendText(""+curT+" "+lst.name+"\n");
		}
		for(int i=0;i<waitB.size();i++) {
			Device_Pcb lst=waitB.get(i);
			taB2.appendText(""+curT+" "+lst.name+"\n");
		}
		for(int i=0;i<waitC.size();i++) {
			Device_Pcb lst=waitC.get(i);
			taC2.appendText(""+curT+" "+lst.name+"\n");
		}

	}
	public boolean isEnd() {//判断是否所有进程已结束
		for(int i=0;i<2;i++) {
			if(A[i].getisOccupy())return false;
		}
		for(int i=0;i<3;i++) {
			if(B[i].getisOccupy())return false;
		}
		for(int i=0;i<3;i++) {
			if(C[i].getisOccupy())return false;
		}
		if(waitA.isEmpty()==false||waitB.isEmpty()==false||waitC.isEmpty()==false||arrr.isEmpty()==false)return false;
		return true;
	}
	public void start_() {//开始模拟
		int delay = 1000;
		ActionListener taskPerformer = new ActionListener() {
			@Override
			public void actionPerformed(java.awt.event.ActionEvent arg0) {
				if(isEnd()==false) {
					curT+=1;
					String ss="Current time:："+curT;
					lbe.setText(ss);

					//释放当前可释放设备 才可以供其他进程占用
					clear(curT);

					//从等待队列开始
					wait_A_go();
					wait_B_go();
					wait_C_go();

					//新到达的进程
					while(arrr.isEmpty()==false&&arrr.get(0).arr<=curT) {
						Arrive(arrr.get(0));
						arrr.remove(0);
					}

					showDetail();
					System.out.println(curT);
				}
				else {
					end.setVisible(true);
				}
			}
		};
		//一秒一次
		tmr=new Timer(delay, taskPerformer);
		state_=1;
		tmr.start();
	}

	public int Arrive(Device_Pcb lst) {//对于当前时间到达的进程 判断是有空闲设备然后立刻执行还是进入等待列表
		int flag=0;
		if(lst.type.equals("A")) {
			for(int i=0;i<2;i++) {
				if(A[i].getisOccupy()==false) {

					//设置终止时间
					lst.setEnd(curT);

					//占有A[i]
					A[i].Occupy(lst);
					flag=1;
					taA.appendText(""+curT+" "+A[i].getPossessor().name+"\n");
					break;
				}
			}
			if(flag==0) {
				waitA.add(lst);
//				taA2.appendText(""+curT+" "+lst.name+"\n");
			}
		}else if(lst.type.equals("B")) {
			for(int i=0;i<3;i++) {
				if(B[i].getisOccupy()==false) {
					lst.setEnd(curT);
					B[i].Occupy(lst);
					flag=1;
					taB.appendText(""+curT+" "+B[i].getPossessor().name+"\n");
					break;
				}
			}
			if(flag==0) {
				waitB.add(lst);
//				taB2.appendText(""+curT+" "+lst.name+"\n");
			}
		}else if(lst.type.equals("C")){
			for(int i=0;i<3;i++) {
				if(C[i].getisOccupy()==false) {
					lst.setEnd(curT);
					C[i].Occupy(lst);
					flag=1;
					taC.appendText(""+curT+" "+C[i].getPossessor().name+"\n");
					break;
				}
			}
			if(flag==0) {
				waitC.add(lst);
//				taC2.appendText(""+curT+" "+lst.name+"\n");

			}
		}else {
			//		System.out.println("Don`t have this Device!");
			return -1;
		}
		if(flag==1) {
			return 1;//success
		}
		else {
			return 0;
		}
	}


	//检测各设备是否有空位 有的话就从等待列表中取进程让第一个执行
	public void wait_A_go() {
		for(int i=0;i<2;i++) {
			if(A[i].getisOccupy()==false) {
				if(waitA.isEmpty()==false) {
					Device_Pcb lst=waitA.get(0);
					lst.setEnd(curT);
					A[i].Occupy(lst);
					taA.appendText(""+curT+" "+lst.name+"\n");
					waitA.remove(0);
				}
			}
		}
	}
	public void wait_B_go() {
		for(int i=0;i<3;i++) {
			if(B[i].getisOccupy()==false) {
				if(waitB.isEmpty()==false) {
					Device_Pcb lst=waitB.get(0);
					lst.setEnd(curT);
					B[i].Occupy(lst);
					taB.appendText(""+curT+" "+lst.name+"\n");
					waitB.remove(0);
				}
			}
		}

	}
	public void wait_C_go() {
		for(int i=0;i<3;i++) {
			if(C[i].getisOccupy()==false) {
				if(waitC.isEmpty()==false) {
					Device_Pcb lst=waitC.get(0);
					lst.setEnd(curT);
					C[i].Occupy(lst);
					taC.appendText(""+curT+" "+lst.name+"\n");
					waitC.remove(0);
				}
			}
		}
	}
}
